Skip to content

chore: design system colour tokens, primitives & Storybook#6883

Open
talissoncosta wants to merge 55 commits intomainfrom
chore/design-system-tokens
Open

chore: design system colour tokens, primitives & Storybook#6883
talissoncosta wants to merge 55 commits intomainfrom
chore/design-system-tokens

Conversation

@talissoncosta
Copy link
Copy Markdown
Contributor

@talissoncosta talissoncosta commented Mar 9, 2026

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Contributes to #6606

Establishes the foundational colour architecture for the design system:

  • Primitive palette: Add _primitives.scss with full 50–950 tonal scales (Tailwind convention) for all 7 colour families. Existing hex anchors are locked — zero visual change to shipped UI.
  • Semantic tokens: Add _tokens.scss with CSS custom properties organised by role (brand, surface, text, border, feedback) with light/dark mode variants. Wire into styles.scss.
  • Alpha colour fix: Align _variables.scss alpha values with correct primitive RGB bases.
  • Storybook 10: Add Storybook 10.3 with webpack5, SCSS support, dark mode toggle, a11y addon, and Flagsmith branding. Dynamic stories for Colour Palette (auto-parsed from _primitives.scss) and Semantic Tokens (auto-discovered from CSS custom properties).
  • Documentation folder: Stories and docs live in a self-contained documentation/ directory, separate from application code — easy to remove or extract into a dedicated design system repo later.
  • Chromatic CI: GitHub Actions workflow for visual regression on PRs (requires CHROMATIC_PROJECT_TOKEN secret).

How did you test this code?

  • npm run build-storybook builds without errors
  • Storybook Colour Palette story shows smooth 50–950 scales for all 7 families
  • Storybook Semantic Tokens story renders live preview with light/dark toggle
  • ENV=local npm run dev — app builds and renders identically (no visual regression)
  • Chromatic CI requires CHROMATIC_PROJECT_TOKEN secret to be added to the repo

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview, Comment Mar 30, 2026 0:32am
flagsmith-frontend-staging Ready Ready Preview, Comment Mar 30, 2026 0:32am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Mar 30, 2026 0:32am

Request Review

@github-actions github-actions bot added the front-end Issue related to the React Front End Dashboard label Mar 9, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.33%. Comparing base (3f71f16) to head (ea5d43e).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6883   +/-   ##
=======================================
  Coverage   98.33%   98.33%           
=======================================
  Files        1337     1337           
  Lines       50010    50012    +2     
=======================================
+ Hits        49178    49180    +2     
  Misses        832      832           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@talissoncosta
Copy link
Copy Markdown
Contributor Author

Blocker: #6866 (Decouple Button from Redux store) should land before or alongside this PR — Button's dependency on AccountStore and Redux state prevents adding Storybook stories for any component that uses <Button>.

@github-actions github-actions bot added the chore label Mar 9, 2026
@talissoncosta talissoncosta linked an issue Mar 10, 2026 that may be closed by this pull request
7 tasks
@talissoncosta talissoncosta force-pushed the chore/design-system-tokens branch from 42b4c1e to 87a4eae Compare March 10, 2026 20:10
@github-actions github-actions bot added chore and removed chore labels Mar 10, 2026
@github-actions github-actions bot added chore and removed chore labels Mar 10, 2026
@github-actions github-actions bot added chore and removed chore labels Mar 10, 2026
@talissoncosta talissoncosta marked this pull request as ready for review March 10, 2026 20:47
@talissoncosta talissoncosta requested review from a team as code owners March 10, 2026 20:47
talissoncosta and others added 27 commits March 27, 2026 11:41
- Move description below the switch+title row (matches old Setting)
- Bump description font-size to 14px (matches fs-small)
- Add header wrapper for switch + title alignment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add project setting toggle using the new SettingRow pattern component.
When enabled, users must assign at least one owner when creating a
feature flag.

- Add require_feature_owners to Project type and UpdateProjectBody
- Create RequireFeatureOwnershipSetting using SettingRow
- Add to Additional Settings section

Note: backend field does not exist yet — frontend is ready for when
the API adds the require_feature_owners field to the Project model.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Generic Skeleton component wrapping the existing .skeleton CSS classes.
Three variants: text (default), badge (pill), circle (avatar/icon).

Stories include:
- Interactive playground with controls
- All variants with descriptions
- When to use / when not to use guidance
- Composition examples (feature row, settings section)
- Dark mode and prefers-reduced-motion notes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add docs-theme.scss with overrides for Storybook's built-in docs
renderer which doesn't respond to our theme toggle. Covers:

Light mode:
- Fix invisible inline code text colour

Dark mode:
- Page background and text colour
- Headings, paragraphs, list items
- Inline code and fenced code blocks with dark backgrounds
- Table rows, headers, and alternating row backgrounds
- Copy button in code blocks
- Horizontal rules and borders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Separate docs page explaining what skeletons are, when to use them,
how the shimmer animation works (dark mode, reduced motion), variant
reference table, composition examples, and best practices.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dark mode is verified by toggling the theme in the toolbar — a
dedicated story for it is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, and proposed components

Three stories under Design System/Typography:
- Current scale: headings, body sizes, and font weights with usage counts
- Known issues: h5 overuse (64x), 49 inline font sizes, no weight tokens,
  fragmented naming
- Proposed components: <Heading> and <Text> with size/weight/colour props
  and polymorphic `as` prop for semantic HTML

This is documentation only — no new components or code changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dard size issue

- Add 'Non-standard sizes' to known issues (11px, 13px are off-grid)
- Add proposed base-4 type scale table (12, 14, 16, 18, 24, 30)
  aligned with industry standards (shadcn, Radix, Atlassian, Carbon)
- Update <Text> component proposal to use 12px/14px instead of 13px
- Each proposed token maps to what it replaces

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Four pages under Presentation/ section in Storybook sidebar:
1. Audit Findings — P0/P1/P2 breakdown, findings tables, momentum
2. Competitor Comparison — LaunchDarkly/PostHog/Unleash side-by-side
3. Roadmap — committed work, timeline, future direction
4. The Ask — what we need, definition of success, punchline

These are presentation-specific and should be removed before merging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three stories introducing the team to Chromatic and MCP:
- What is Chromatic: publishing, visual regression, review workflow
- What is Storybook MCP: how AI reads component metadata, what it sees
- What this enables: before/after table, virtuous cycle diagram, setup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two stories addressing expected pushback:
- Maintenance model: who does what, when, and what doesn't change
- Common questions: 6 FAQ cards covering slowdown concerns,
  adoption, over-engineering, bottleneck prevention, backend
  engineer experience, and the cost of inaction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Four benefits that come automatically with every story:
- Visual regression testing (Chromatic)
- Accessibility audit (axe-core via a11y addon)
- Living documentation
- AI context via MCP

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the four free benefits (visual regression, a11y audit, living
docs, AI context via MCP) from the Maintenance story into its own
sidebar item for easier navigation during the presentation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…arison

- Reframe 'Competitor Comparison' as 'Industry Validation' with
  'Where we already are' section showing Flagsmith's progress
- Reorder: Chromatic & MCP moves before Roadmap and The Ask so the
  live demo lands right after explaining MCP
- New flow: Audit → Validation → Chromatic/MCP → DEMO → Roadmap → Ask → FAQ

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Storybook forces rendering in isolation — if a component can't render
without the full app, it's too coupled. We already found this with
Setting, Tabs, and CategoricalPalette which imported the Redux store
transitively and couldn't render in Storybook.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changed '5 purples' to '5 different shades of our brand purple
scattered across the codebase' for clarity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- P0: 3 parallel theming mechanisms (.dark, getDarkMode, data-bs-theme)
  that semantic tokens will unify
- P1: 280+ hardcoded hex values in TSX not tied to any token
- New Accessibility section: secondary text below WCAG AA, no a11y CI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y-changed

Explain that Chromatic only runs on frontend changes (CI path filters)
and skips unchanged stories (--only-changed flag) to minimise snapshot
consumption.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove files superseded by the renumbered versions
(03-ChromaticAndMCP, 04-Roadmap, 05-TheAsk).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure feedback tokens from standalone categories
(--color-danger-*, --color-success-*) to element-first tokens
within each category (--color-text-danger, --color-surface-danger,
--color-border-danger, --color-icon-danger).

Each token now has one job: text tokens optimised for contrast,
surface tokens for subtle backgrounds, border and icon tokens
for their specific context.

New categories added:
- Icon: default, secondary, disabled + feedback variants
- Surface: feedback variants (danger, success, warning, info)
- Text: feedback variants
- Border: feedback variants

Also adds common/theme/tokens.ts for JS/TS access to tokens
(for chart libraries, inline SVG fills, runtime colour logic).

Updates Banner component to use new token names.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- --color-text-disabled: greyed out labels, disabled button text
- --color-border-disabled: disabled input/control borders
- --color-icon-disabled: greyed out icons in disabled controls
- --color-icon-secondary: secondary emphasis icons

Light and dark mode values included. JS/TS tokens updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ructure

- Replace 'Feedback' category with 'Icon' category in the table
- Update all categories to mention feedback variants within them
- Update naming convention: category is now element type (surface, text,
  border, icon), variant includes feedback (danger, success, etc.)
- Update code examples to show element-first tokens
  (--color-surface-danger, --color-text-danger, --color-border-danger)
- Update common mistakes: warn against using one token for multiple
  element types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Brand is not an element type — it's a colour meaning. In the
element-first model, brand purple becomes 'action' within each
category:
- --color-surface-action (button bg, replaces --color-brand-default)
- --color-surface-action-hover, action-active, action-subtle, action-muted
- --color-text-action (link text, CTA text)
- --color-border-action (focused input border)
- --color-icon-action (interactive icon fill)

Four pure element categories remain: Surface, Text, Border, Icon.

Also renames Patterns/Setting to Patterns/SettingRow in Storybook.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…okens

Extend the design token system beyond colour to cover the full taxonomy.
Values align with existing _variables.scss to enable gradual migration.
CSS custom properties are the single source of truth — both SCSS and
future Tailwind config will consume them via var().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update from '3 icons' to '~35 icons across 42 files' to reflect
actual codebase usage discovered during issue verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… and maintenance guide

Each story includes visual previews and usage descriptions that
Storybook MCP exposes to AI agents — token intent, pairing rules,
and when-to-use guidance. The maintenance guide documents how to
add, modify, or remove tokens across the system.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename --space-100/200/400 to --space-1/2/4 etc. so token names
map directly to Tailwind utility classes (p-4 = var(--space-4) = 16px).
No mental translation between naming systems.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
}

function escapeJsx(str: string): string {
return str.replace(/'/g, "\\'")

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding

This does not escape backslash characters in the input.

Copilot Autofix

AI about 2 hours ago

In general, when escaping characters for inclusion in a JS/JSX single-quoted literal, you must first escape backslashes (\\\), then escape single quotes ('\'), both with global replacements. This ensures any pre-existing escape sequences cannot “eat” your escaping backslashes and leave meta-characters unescaped.

The single best fix here is to update escapeJsx so that it performs two successive global replacements: first on backslashes, then on single quotes. No other functionality changes are required. Concretely, in frontend/scripts/generate-token-docs.ts, lines 42–44 should be updated so that escapeJsx returns str.replace(/\\/g, '\\\\').replace(/'/g, "\\'"). This uses standard JavaScript String.prototype.replace with global regular expressions and needs no additional imports or helper methods.

Suggested changeset 1
frontend/scripts/generate-token-docs.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/frontend/scripts/generate-token-docs.ts b/frontend/scripts/generate-token-docs.ts
--- a/frontend/scripts/generate-token-docs.ts
+++ b/frontend/scripts/generate-token-docs.ts
@@ -40,7 +40,8 @@
 }
 
 function escapeJsx(str: string): string {
-  return str.replace(/'/g, "\\'")
+  // Escape backslashes first, then single quotes, for safe embedding in single-quoted JSX
+  return str.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
 }
 
 type FlatToken = {
EOF
@@ -40,7 +40,8 @@
}

function escapeJsx(str: string): string {
return str.replace(/'/g, "\\'")
// Escape backslashes first, then single quotes, for safe embedding in single-quoted JSX
return str.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
}

type FlatToken = {
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: Introduce semantic colour tokens and primitive palette

1 participant